#ifndef _INCLUDE_COMMONDEF_H_
#define _INCLUDE_COMMONDEF_H_

#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#define PAGE_SIZE 4096

#define _1K                     0x00000400

#define RTCALL
#define DECLCALLBACK(type) type
#define RT_FAR
#define RT_FLEXIBLE_ARRAY

#define DECLINLINE(type) inline type

#define RT_UNTRUSTED_VOLATILE_GUEST volatile
#define RT_UNTRUSTED_VOLATILE_HSTGST volatile

#define RT_MIN(a, b) ((a) < (b) ? (a) : (b))
#define RT_MAX(a, b) ((a) > (b) ? (a) : (b))

#define RT_ELEMENTS(aArray)                     ( sizeof(aArray) / sizeof((aArray)[0]) )

#if defined(__cplusplus)
# define RT_C_DECLS_BEGIN extern "C" {
# define RT_C_DECLS_END   }
#else
# define RT_C_DECLS_BEGIN
# define RT_C_DECLS_END
#endif

#define VINF_SUCCESS                        0
#define VERR_GENERAL_FAILURE                (-1)
#define VERR_INVALID_PARAMETER              (-2)
#define VERR_INVALID_HANDLE                 (-4)
#define VERR_INVALID_POINTER                (-6)
#define VERR_NO_MEMORY                      (-8)
#define VERR_NOT_IMPLEMENTED                (-12)
#define VERR_NOT_EQUAL                      (-18)
#define VERR_INVALID_FUNCTION               (-36)
#define VERR_NOT_SUPPORTED                  (-37)
#define VERR_TOO_MUCH_DATA                  (-42)
#define VERR_TRY_AGAIN                      (-52)
#define VERR_NOT_FOUND                      (-78)
#define VERR_INVALID_STATE                  (-79)
#define VERR_OUT_OF_RESOURCES               (-80)
#define VERR_NO_MORE_HANDLES                (-81)
#define VERR_ALREADY_EXISTS                 (-105)
#define VERR_INTERNAL_ERROR                 (-225)

#define AssertCompileSize(type, size)
#define AssertCompileMemberOffset(type, member, off)
#define AssertCompile(expr) /* NOP */
#define AssertBreakStmt(expr, stmt)
#define AssertBreakpoint()     do { } while (0)
#define AssertPtrReturn(pv, rcRet) do { if (pv) {} else return(rcRet); } while(0)

#define AssertReleaseFailed()  do { } while (0)

# define AssertBreak(expr) \
    if (!!(expr)) \
    { /* likely */ } \
    else \
        break

# define AssertReturn(expr, rc) \
    do { \
        if ((!!(expr))) \
        { /* likely */ } \
        else \
            return (rc); \
    } while (0)

# define AssertReturnStmt(expr, stmt, rc) \
    do { \
        if ((!!(expr))) \
        { /* likely */ } \
        else \
        { \
            stmt; \
            return (rc); \
        } \
    } while (0)

# define AssertMsgReturn(expr, a, rc) \
    do { \
        if ((!!(expr))) \
        { /* likely */ } \
        else \
            return (rc); \
    } while (0)

# define AssertReturnVoidStmt(expr, stmt) \
    do { \
        if (!!(expr)) \
        { /* likely */ } \
        else \
        { \
            stmt; \
            return; \
        } \
    } while (0)

# define AssertFailedReturnVoidStmt(stmt)  \
    do { \
        stmt; \
        return; \
    } while (0)

# define AssertReturnVoid(expr) \
    do { \
        if (!!(expr)) \
        { /* likely */ } \
        else \
            return; \
    } while (0)

# define AssertMsgReturnVoidStmt(expr, a, stmt) \
    do { \
        if (!!(expr)) \
        { /* likely */ } \
        else \
        { \
            stmt; \
            return; \
        } \
    } while (0)

# define AssertStmt(expr, stmt)  \
    do { \
        if (!!(expr)) \
        { /* likely */ } \
        else \
        { \
            stmt; \
        } \
    } while (0)

#define AssertMsg(expr, a)  do { } while (0)
#define Assert(T) /*NOP*/
#define AssertFailed()         do { } while (0)
#define AssertMsgRCReturn(rc, msg, rcRet) \
    do { AssertMsgReturn(RT_SUCCESS_NP(rc), msg, rcRet); NOREF(rc); } while (0)
#define AssertMsgRCReturnVoidStmt(rc, msg, stmt) \
    do { AssertMsgReturnVoidStmt(RT_SUCCESS_NP(rc), msg, stmt); NOREF(rc); } while (0)
#define AssertRCReturn(rc, rcRet)   AssertMsgRCReturn(rc, ("%Rra\n", (rc)), rcRet)
#define AssertRCReturnVoidStmt(rc, stmt) AssertMsgRCReturnVoidStmt(rc, ("%Rra\n", (rc)), stmt)

#define BP_WARN() do { } while(0)
#define WARN(_a) do { } while(0)
#define LOG(_a)
#define LOGREL(_a) 
#define LOGF_ENTER() 
#define LOGF_LEAVE() 
#define LOGREL_EXACT(_a) 
#define LOGF_EXACT(_a) 

#define RT_SUCCESS(rc)      ( /*likely*/((rc) == 0) )
#define RT_BOOL(Value)                          ( !!(Value) )

/** @def RT_SIZEOFMEMB
 * Get the size of a structure member.
 *
 * @returns size of the structure member.
 * @param   type    Structure type.
 * @param   member  Member.
 */
#define RT_SIZEOFMEMB(type, member)             ( sizeof(((type *)(void *)0)->member) )

#define DECLCALLBACKMEMBER(type, name) type (* name)

 /**
  * The size of a rectangle.
  */
typedef struct RTRECTSIZE
{
    /** The width (along the x-axis). */
    uint32_t    cx;
    /** The height (along the y-axis). */
    uint32_t    cy;
} RTRECTSIZE, *PRTRECTSIZE;
/** Pointer to a const rectangle size. */
typedef const RTRECTSIZE *PCRTRECTSIZE;

/**
  * Byte zero the specified memory area.
  *
  * This will call memset, bzero or some compiler intrinsic to clear the
  * specified bytes of memory.
  *
  * @param   pv          Pointer to the memory.
  * @param   cb          The number of bytes to clear. Please, don't pass 0.
  *
  * @remarks Because the macro may use memset it has been placed in string.h
  *          instead of cdefs.h to avoid build issues because someone forgot
  *          to include this header.
  *
  * @ingroup grp_rt_cdefs
  */
#define RT_BZERO(pv, cb)    do { memset((pv), 0, cb); } while (0)

/**
 * Byte zero the specified object.
 *
 * This will use sizeof(Obj) to figure the size and will call memset, bzero
 * or some compiler intrinsic to perform the actual zeroing.
 *
 * @param   Obj     The object to zero. Make sure to dereference pointers.
 *
 * @remarks Because the macro may use memset it has been placed in string.h
 *          instead of cdefs.h to avoid build issues because someone forgot
 *          to include this header.
 *
 * @ingroup grp_rt_cdefs
 */
#define RT_ZERO(Obj)        RT_BZERO(&(Obj), sizeof(Obj))

#define RT_NOREF(t) (void)t
#define NOREF(t) RT_NOREF(t)
#define RT_NOREF1(t) (void)t
#define RT_NOREF2(t1, t2) do { (void)t1; (void)t2; } while (0)
#define RT_NOREF3(var1, var2, var3)               RT_NOREF(var1); RT_NOREF2(var2, var3)
#define RT_NOREF4(var1, var2, var3, var4)         RT_NOREF(var1); RT_NOREF3(var2, var3, var4)
#define RT_NOREF5(var1, var2, var3, var4, var5)   RT_NOREF(var1); RT_NOREF4(var2, var3, var4, var5)
#define RT_NOREF6(var1, var2, var3, var4, var5, var6)   RT_NOREF(var1); RT_NOREF5(var2, var3, var4, var5, var6)
#define RT_NOREF7(var1, var2, var3, var4, var5, var6, var7)   RT_NOREF(var1); RT_NOREF6(var2, var3, var4, var5, var6, var7)
#define RT_FALL_THRU() (void)0

#define RT_UOFFSETOF_DYN(type, memberarray)    ( (uintptr_t)&( ((type *)(void *)0)->memberarray) )
#define RT_UOFFSETOF(type, member) offsetof(type, member)

#define RT_NO_THROW_DEF
#define RT_NO_THROW_PROTO
#define RTDECL(T) T

#define RTMEM_TAG   (__FILE__)
#define RT_SUCCESS_NP(rc)   ( (int)(rc) >= VINF_SUCCESS )
#define RT_FAILURE(rc)      (!RT_SUCCESS_NP(rc))

static inline void * RTMemAllocTag(size_t cb, const char *pszTag)
{
    RT_NOREF(pszTag);

    void *pv = malloc(cb);
    return pv;
}


/**
 * Allocates zero'd memory with custom tag.
 *
 * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
 * memory. This keeps the code smaller and the heap can skip the memset
 * in about 0.42% of calls :-).
 *
 * @returns Pointer to the allocated memory.
 * @returns NULL on failure.
 * @param   cb      Size in bytes of the memory block to allocated.
 * @param   pszTag  Allocation tag used for statistics and such.
 */
static inline void * RTMemAllocZTag(size_t cb, const char *pszTag)
{
    RT_NOREF(pszTag);
    void *pv = calloc(1, cb);
    return pv;
}

/**
 * Frees memory.
 *
 * @param   pv      Pointer to memory block.
 */
static inline void RTMemFree(void *pv)
{
    if (pv) {
        free(pv);
    }
}

/**
 * Allocates zero'd memory with default tag.
 *
 * Instead of memset(pv, 0, sizeof()) use this when you want zero'd
 * memory. This keeps the code smaller and the heap can skip the memset
 * in about 0.42% of calls :-).
 *
 * @returns Pointer to the allocated memory.
 * @returns NULL on failure.
 * @param   cb      Size in bytes of the memory block to allocated.
 */
#define RTMemAllocZ(cb)                 RTMemAllocZTag((cb), RTMEM_TAG)

/**
 * Allocates memory with default tag.
 *
 * @returns Pointer to the allocated memory.
 * @returns NULL on failure, assertion raised in strict builds.
 * @param   cb      Size in bytes of the memory block to allocated.
 */
#define RTMemAlloc(cb)                  RTMemAllocTag((cb), RTMEM_TAG)

#define RT_BIT(bit)                             ( 1U << (bit) )
#define RT_BIT_32(bit)                          ( UINT32_C(1) << (bit) )
#define RT_BIT_64(bit)                          ( UINT64_C(1) << (bit) )
#define RT_BIT_Z(a_iBit)                        ( (size_t)(1) << (a_iBit) )

#define RT_ALIGN(u, uAlignment)                 ( ((u) + ((uAlignment) - 1)) & ~((uAlignment) - 1) )
#define RT_ALIGN_T(u, uAlignment, type)         ( ((type)(u) + ((uAlignment) - 1)) & ~(type)((uAlignment) - 1) )
#define RT_ALIGN_32(u32, uAlignment)            RT_ALIGN_T(u32, uAlignment, uint32_t)
#define RT_ALIGN_64(u64, uAlignment)            RT_ALIGN_T(u64, uAlignment, uint64_t)
#define RT_ALIGN_Z(cb, uAlignment)              RT_ALIGN_T(cb, uAlignment, size_t)
#define RT_ALIGN_P(pv, uAlignment)              RT_ALIGN_PT(pv, uAlignment, void *)
#define RT_ALIGN_PT(u, uAlignment, CastType)    ( (CastType)RT_ALIGN_T(u, uAlignment, uintptr_t) )

#endif
